#region LICENSE

// The contents of this file are subject to the Common Public Attribution
// License Version 1.0. (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// https://github.com/NiclasOlofsson/MiNET/blob/master/LICENSE. 
// The License is based on the Mozilla Public License Version 1.1, but Sections 14 
// and 15 have been added to cover use of software over a computer network and 
// provide for limited attribution for the Original Developer. In addition, Exhibit A has 
// been modified to be consistent with Exhibit B.
// 
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
// the specific language governing rights and limitations under the License.
// 
// The Original Code is MiNET.
// 
// The Original Developer is the Initial Developer.  The Initial Developer of
// the Original Code is Niclas Olofsson.
// 
// All portions of the code written by Niclas Olofsson are Copyright (c) 2014-2018 Niclas Olofsson. 
// All Rights Reserved.

#endregion

using System;
using System.Collections.Generic;
using System.Linq;

namespace MiNET.Utils.Skins
{
	public class GeometryModel : Dictionary<string, Geometry>, ICloneable
	{
		public Geometry FindGeometry(string geometryName, bool matchPartial = true)
		{
			string fullName = Keys.FirstOrDefault(m => matchPartial ? m.StartsWith(geometryName) : m.Equals(geometryName, StringComparison.InvariantCultureIgnoreCase));
			if (fullName == null) return null;

			var geometry = this[fullName];
			geometry.Name = fullName;

			if (fullName.Contains(":"))
			{
				geometry.BaseGeometry = fullName.Split(':')[1];
			}

			return geometry;
		}

		public Geometry CollapseToDerived(Geometry derived)
		{
			Geometry collapsed = (Geometry) derived.Clone();

			if (collapsed.BaseGeometry != null)
			{
				Geometry baseGeometry = (Geometry) FindGeometry(collapsed.BaseGeometry).Clone();

				foreach (var bone in baseGeometry.Bones)
				{
					if (collapsed.Bones.SingleOrDefault(b => b.Name == bone.Name) == null)
					{
						collapsed.Bones.Add(bone);
					}
				}
			}

			return collapsed;
		}

		public object Clone()
		{
			var model = (GeometryModel) MemberwiseClone();
			foreach (var records in this)
			{
				model.Add(records.Key, (Geometry) records.Value.Clone());
			}

			return model;
		}
	}
}